#include <cstdlib>
#include <ctime>
using namespace std;
#include <QCoreApplication>
#include <QDebug>
#include <QFile>

#include "Simulator.h"
#include "Arrival/DeterministicArrival.h"
#include "Arrival/RandomArrival.h"
#include "Server/DeterministicServer.h"
#include "Server/RandomServer.h"
#include "Random/ErlangRandom.h"
#include "TheoreticalValue.h"


int main(int argc, char* argv[])
{
    QTextStream cout(stdout,  QIODevice::WriteOnly);
    if(argc != 6)
    {
        cout<<"QueueTheory.exe queue lambda miu k T"<<endl;
        return 0;
    }

    srand(time(0));

    double lambda = QString(argv[2]).toDouble();
    double miu = QString(argv[3]).toDouble();
    int k = QString(argv[4]).toInt();
    int t = QString(argv[5]).toInt();

    int repeat = 100;

    QFile file(QString("%1.%2.%3.%4.%5.csv").arg(argv[1]).arg(lambda).arg(miu).arg(k).arg(t));
    file.open(QFile::WriteOnly);
    QTextStream out(&file);




    if(QString::compare(QString(argv[1]), QString("Ek_D_1")) == 0)
    {
        QMap<int, double> bk;
        bk[2] = 2;
        bk[4] = 3.5;
        bk[8] = 6;

        ErlangRandom arrivalRandom(lambda, k);

        out<<"Result:"<<endl;
        double sum = 0;
        for(int i = 0; i < repeat; i++)
        {
            RandomArrival eArrival(&arrivalRandom);
            DeterministicServer dServer(miu);

            Simulator simulator(&eArrival, &dServer, t);

            SimulationResult result = simulator.Run();
            out<<result.EWq()<<endl;
            sum += result.EWq();
        }
        out<<"Average:\n"<<sum / repeat<<endl;
        out<<"Expected EWq:\n"<<TheoreticalValue::Ek_D_1_EWq(lambda, miu, bk[k])<<endl;
    }
    else if(QString::compare(QString(argv[1]), QString("D_Ek_1")) == 0)
    {
        QMap<int, double> bk;
        bk[1] = 0.93;
        bk[2] = 1.9;
        bk[4] = 3.8;
        bk[8] = 6.5;

        ErlangRandom random(miu, k);

        out<<"Result:"<<endl;
        double sum = 0;
        for(int i = 0; i < repeat; i++)
        {
            DeterministicArrival dArrival(lambda);
            RandomServer eServer(&random);
            Simulator simulator(&dArrival, &eServer, t);

            SimulationResult result = simulator.Run();
            out<<result.EWq()<<endl;
            sum += result.EWq();
        }
        out<<"Average:\n"<<sum / repeat<<endl;
        out<<"Expected ELq:\n"<<TheoreticalValue::D_Ek_1_ELq(lambda, miu, bk[k])<<endl;

    }
    else
    {
        cout<<"Unsupport queue model"<<endl;
    }
    out.flush();
    file.close();
    return 0;
}
